/**
 * Created by cqb32_000 on 2016-12-16.
 */

var fork = require('child_process').fork;
var jsts = require("jsts");
var wktreader = new jsts.io.WKTReader();
var Utils = require("../workers/Utils");
var moment = require("moment");
var Cesium = require("cesium");

module.exports = {

    /**
     *
     * @param mis_id
     * @param sen_id
     * @param type
     * @param startDate
     * @param endDate
     */
    doCalculate: function(mis_id, sen_id, type, startDate, endDate, callback){
        var p1 = new Promise((resolve, reject)=>{
            this.db.Mission.find({where: {mis_id: mis_id}}).then(function(mission){
                resolve(mission.dataValues);
            });
        });

        var p2 = new Promise((resolve, reject)=>{
            this.getSensor(sen_id, (sensors)=>{
                resolve(sensors);
            }, this);
        });

        Promise.all([p1, p2]).then((ret)=>{
            if(type === "fullCover"){
                startDate = moment().format("YYYY-MM-DD");
                endDate = null;
            }
            this.doCalculateTimes(ret[0], ret[1], startDate, endDate, callback);
        });
    },

    doCalculateTimes: function(mis, sensors, startDate, endDate, callback){
        sensors.forEach((sensor)=>{
            this.buildSatelliteRec(sensor);
            console.log(sensor.max_tilt);
        });

        var geometry = wktreader.read(mis.mis_geometry);
        mis.area = geometry.getArea();
        mis.orignarea = mis.area;
        mis.remaindwkt = mis.mis_geometry;


        this._executeNextDay(sensors, startDate, endDate, mis, callback);
    },

    _executeNextDay: function(sats, startTime, endTime, mis, callback){
        var retTimes = [];
        var getTimeWorker = fork('./workers/getTimeWorker.js');
        var params = {
            mis: mis,
            sats: sats,
            startTime: startTime,
        };
        getTimeWorker.send(params);

        getTimeWorker.on("message", (times)=>{
            var length = times ? times.length : 0, finished = 0;
            var isfinilize = false;

            if(endTime){
                var sd = moment(params.startTime);
                sd.add(1,"days");
                var ed = moment(endTime);

                if(sd.isAfter(ed)){
                    isfinilize = true;
                }
            }

            var getTiltWorker = fork('./workers/getTiltWorker.js');
            getTiltWorker.on("message", (data)=>{
                //完成的个数
                finished++;
                if(data.time.tilt != undefined){
                    retTimes.push({
                        wkt: data.stripeWKT,
                        start: data.start,
                        end: data.end,
                        tilt: data.time.tilt,
                        orbitnum: data.time.orbitnum,
                        range: data.time.range,
                        scenenum: data.time.scenenum
                    });
                }
                //都完成
                if(finished == length){
                    //没有到规定时间并且也没有全覆盖完，进入下一天计算
                    if(!isfinilize && data.lastarea != 0){
                        var st = moment(params.startTime);
                        st.add(1, "days");
                        params.startTime = st.format("YYYY-MM-DD");
                        params.mis.remaindwkt = data.remaindwkt;

                        params.mis.orignarea = data.lastarea;
                        getTiltWorker.kill();
                        getTimeWorker.send(params);
                    }else{//到规定的时间或者已经全覆盖
                        params.mis.remaindwkt = data.remaindwkt;
                        params.mis.orignarea = data.lastarea;

                        getTiltWorker.kill();
                        getTimeWorker.kill();
                        callback ? callback({
                            times: retTimes,
                            cover: Math.round((1- params.mis.orignarea / params.mis.area) * 100)
                        }) : false;
                        console.log("ending.................");
                    }
                }else{//下一个条带
                    getTiltWorker.send(times[finished]);
                }
            });

            //这一天中有过轨条带计算最佳侧摆的条带
            if(length){
                getTiltWorker.send(times[finished]);
            }else{
                if(isfinilize) {
                    getTiltWorker.kill();
                    getTimeWorker.kill();
                    callback ? callback({
                        times: retTimes,
                        cover: Math.round((1 - params.mis.orignarea / params.mis.area) * 100)
                    }) : false;
                    console.log("ending.................");
                }else {
                    var st = moment(params.startTime);
                    st.add(1, "days");
                    params.startTime = st.format("YYYY-MM-DD");
                    getTiltWorker.kill();
                    getTimeWorker.send(params);
                }
            }


            // if(times.length){
            //     getTiltWorker.send(times[1]);
            // }else{
            //     var st = moment(params.startTime);
            //     st.add(1, "days");
            //     params.startTime = st.format("YYYY-MM-DD");
            //     getTimeWorker.send(params);
            // }
        });
    },

    buildSatelliteRec: function(sat){
        if(!sat.satData){
            var tles = sat.sat_tle.split(/\n+/g);
            sat.tle0 = sat.sat_id;
            sat.tle1 = tles[0];
            sat.tle2 = tles[1];

            var ret = Utils.getSatrecsFromTLE([sat.tle0, sat.tle1, sat.tle2]);
            sat.satData = ret.satData;
            sat.satrec = ret.satrec;
        }
    },

    /**
     *
     * @param sen_id
     * @param callback
     */
    getSensor: function(sen_ids, callback){
        var sql = `select a.*,b.* from mps_satellite a, mps_sensor b 
        where b.sat_id=a.sat_id and b.sen_id in (`;
        var ids = sen_ids.split(",");
        var id_map = {};
        ids = ids.map(function(id){
            id_map[id.split(":")[0]] = id.split(":")[1];
            return id.split(":")[0];
        });
        var places = new Array(ids.length+1);
        sql += places.join("?,");
        sql = sql.substring(0, sql.length-1);
        sql += ")";

        db.query(sql, {
            raw: true,
            type: db.QueryTypes.SELECT,
            replacements: ids
        }).then((res)=>{
            if(res){
                res.forEach((sat)=>{
                    if(id_map[sat.sen_id] != undefined){
                        sat.max_tilt = parseFloat(id_map[sat.sen_id]);
                    }else{
                        sat.max_tilt = sat.sen_tilt;
                    }
                });
            }
            callback(res);
        }).catch((err)=>{
            callback(null);
        });
    }
};